#ifndef PARTITION_H
#define PARTITION_H

#include <stdint.h>

/* ********************************************************************************
 */

#define LEN_128 128
#define LEN_1024 1024

/* ********************************************************************************
 */
typedef struct {
    int16_t rootId;
} DisjointSetElem;

typedef struct {
    DisjointSetElem set[LEN_1024];
    uint32_t capacity;
} DisjointSet_L1024;

typedef struct {
    int16_t array[LEN_128];
    uint32_t size;
    uint32_t capacity;
} Cluster_L128;

/* ********************************************************************************
 */

typedef enum {
    PT_ERROR,
    PT_SAME_SET,
    PT_DIFF_SET
} PT_FIND_RESULT;

typedef void (*INIT_L1024)(DisjointSet_L1024 *);
typedef void (*UNION_L1024)(DisjointSet_L1024 *, int16_t, int16_t);
typedef PT_FIND_RESULT (*FIND_L1024)(DisjointSet_L1024 *, int16_t, int16_t);
typedef void (*LINK_L1024)(DisjointSet_L1024 *, int16_t, int16_t);
typedef int16_t (*ROOT_L1024)(DisjointSet_L1024 *, int16_t);

typedef struct {
    INIT_L1024 initSet;
    UNION_L1024 unionSet;
    FIND_L1024 findSet;
    ROOT_L1024 rootSet;
} DisjSetInterface_L1024;

extern const DisjSetInterface_L1024 iDisjSet_L1024;

/* ********************************************************************************
 */

void parition(
        const float * const mat,
        const uint32_t row,
        const uint32_t col,
        const uint32_t stride,
        const float thres,
        DisjointSet_L1024 *setBuf,
        Cluster_L128 *clusters);

#endif // PARTITION_H

